﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RATSharp.Rest;
using RATSharp.Model;
using RATSharp.Collection;
using System.Threading.Tasks;
using RATSharp.Validator;

namespace RATSharp.Cal
{
    delegate void CalendarDateTimeHandler(DateTime dateTime);
    delegate void CalendarPeriodHandler(Period period);
    class Calendar
    {
        private int year;
        private int month;
        public IReservationHandler reservationHandler { get; set; }
        private AbstractCalendarDataProvider dataProvider;

        delegate void CalendarDayHandler(int year, int month, int day);


       public Calendar(int year, int month, AbstractCalendarDataProvider dataProvider)
       {
           this.dataProvider = dataProvider;
           this.year = year;
           this.month = month;
       }

        public void init()
        {
                bool stepback = false;
                dataProvider.invalidate();
                if (dataProvider.data == null)
                {
                    return;
                }
                while (!stepback)
                {

                    //TODO: poradne to datum
                    MenuList<MenuItem<string, CalendarDayHandler>, MenuItem<string, CalendarDayHandler>> calendarList = 
                        new MenuList<MenuItem<string, CalendarDayHandler>, MenuItem<string, CalendarDayHandler>>("Calendar - ");
                    int daysInMonth = System.DateTime.DaysInMonth(year, month);

                    for (int i = 1; i <= daysInMonth; i++)
                    {
                        string itemName = String.Format("{0:dd.MM.}", (new DateTime(year, month, i)));
                        List<Period> values;
                        if (dataProvider.data.TryGetValue(i, out values))
                        {
                            itemName += "*";
                        }

                        calendarList.Add(new MenuItem<string, CalendarDayHandler>(itemName, new CalendarDayHandler(handleCalendayDay)));
                    }

                    calendarList.Add(new MenuItem<string, CalendarDayHandler>("Step Back", delegate(int delYear, int delMonth, int delDay) { stepback = true; }));
                    Console.Write(calendarList);

                    int selectedItem = MenuUtilities.GetSimpleInput(new IntRangeInputValidator(1, daysInMonth + 1));

                    calendarList.ElementAt(selectedItem - 1).menuHandler(year, month, selectedItem);
                }

        }

        private void handleCalendayDay(int year, int month, int day)
        {
            bool stepback = false;
   

            while (!stepback)
            {
                List<Period> periodsInSelectedDay;
                dataProvider.data.TryGetValue(day, out periodsInSelectedDay);

                DateTime dateTime = new DateTime(year, month, day);

                MenuList<MenuItem<Period, CalendarPeriodHandler>, MenuItem<string, CalendarDateTimeHandler>> dayList =
                    new MenuList<MenuItem<Period, CalendarPeriodHandler>, MenuItem<string, CalendarDateTimeHandler>>("Calendar - " + String.Format("{0:dd.MM yyyy}", dateTime));

                if (periodsInSelectedDay != null)
                {
                    foreach (Period period in periodsInSelectedDay)
                    {
                        dayList.Add(new MenuItem<Period, CalendarPeriodHandler>(period, new CalendarPeriodHandler(reservationHandler.handle)));
                    }
                }

                if (reservationHandler.getAllowedCalendarActions() != null && DateTime.Compare(dateTime, DateTime.Now.Date) >= 0)
                {
                dayList.AddAdditional(reservationHandler.getAllowedCalendarActions());
                    }
                dayList.AddAdditional(new MenuItem<string, CalendarDateTimeHandler>("Step Back", delegate(DateTime dtm) { stepback = true; }));


                Console.Write(dayList);
                int choice = MenuUtilities.GetSimpleInput(new IntRangeInputValidator(1, dayList.fullCount)) - 1;

                if (choice < dayList.Count)
                {
                    dayList.ElementAt(choice).menuHandler(dayList.ElementAt(choice).value);
                }
                else
                {
                    dayList.GetAdditional(choice).menuHandler(dateTime);
                }
            }
        }

    }
}
